﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections;
using System.Text.RegularExpressions;
 

namespace OutillageTests
{
    public class CyclomaticNumber
    {
        public static decimal fileComplexity = 1;
        public static decimal methodCount = 0;
 
        public static void Complexity(string path)
        {
            try
            {
                if (path.EndsWith(".cs") || path.EndsWith(".cpp") || path.EndsWith(".c"))
                {
                    ComplexityCalculator(path);
                }
                else
                {
                    DirectoryParser(path);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Path not found:  " + path);
                Console.WriteLine(e);
            }
        }
 
        private static void DirectoryParser(string projectDirectoryPath)
        {
            // Process the list of files found in the directory.
            string[] fileEntries = Directory.GetFiles(projectDirectoryPath);
            foreach (string fileName in fileEntries)
                ComplexityCalculator(fileName);
              
          
            // Recurse into subdirectories of this directory.
            string[] subdirectoryEntries = Directory.GetDirectories(projectDirectoryPath);
            foreach (string subdirectory in subdirectoryEntries)
                DirectoryParser(subdirectory);
        }
 
        private static decimal ComplexityCalculator(string fileName)
        {
           
            if (fileName.EndsWith(".cs") || fileName.EndsWith(".cpp") || fileName.EndsWith(".c"))
            {
                try
                {
                    using (StreamReader sourceCode = new StreamReader(fileName))
                    {
                        String linesOfSource = sourceCode.ReadToEnd();
                       
                        //methodCount = methodCount + FindNumberOfMethodsInClasses(linesOfSource);
                        fileComplexity = fileComplexity + Counter(linesOfSource);
                        return fileComplexity;
                    }
                  
                }
                catch (Exception e)
                {
                    Console.WriteLine("There was an error reading the source file:  " + fileName);
                    Console.WriteLine(e);
                    return 0;
                }
            }
            else
            {
                Console.WriteLine("Unsupported file type:  " + fileName);
                return 0;
            }
        }
 
        
        private static decimal Counter(string theSourceFileTurnedIntoABigString)
        {
            decimal complexityCount = 0;
            String[] matchString = { "(if)(?(\\s)\\(|\\()", "else", "(&&)", "(\\|\\|)", "(foreach)",
                                       "(\\(for)", "(do)", "(while)", "(switch)", "(case)(?(\\s)\\(|\\()",
                                       "(try)(?(\\r\\n)\\{|\\{)", "(catch)(?(\\s)\\(|\\()", "(\\?\\:)",
                                       "(else if)(?(\\s)\\(|\\()" };
           
            foreach (string regexSelectorString in matchString)
            {
                Regex selector = new Regex(regexSelectorString);
                MatchCollection selectorMatch = selector.Matches(theSourceFileTurnedIntoABigString);
                complexityCount += selectorMatch.Count;
            }
           
            return complexityCount;
        }
    }
}

